<?php
/**
 * ReportAgent.php
 * description:
 * Created by www.
 * User: SCF
 * Date: 2018/11/14 15:08
 *
 */

namespace App\Console\Commands\ReportData;

use App\Models\MoneyDeposit;
use App\Models\PayVendor;
use App\Models\PayVendorScene;
use App\Models\ReportOnlineRecharge as ReportOnlineRechargeModel;
use common\enum\MoneyDepositEnum;
use common\enum\ReportOnlineRechargeEnum;
use function GuzzleHttp\Psr7\str;
use Illuminate\Support\Facades\DB;

class ReportOnlineRecharge extends BaseReport
{
    protected $signature = self::PREFIX . 'report_online_recharge {--reload=} {--begin=} {--end=} {--command=}';

    protected $description = '线上充值统计';

    public $reportName = "ReportOnlineRecharge";

    /**
     * 获取需要处理的数据
     */
    public function getData($beginTime, $endTime)
    {
        // $beginTime = '2018-10-16 00:00:00';
        // $endTime = '2018-12-05 23:59:59';
        //endTime每次和当前时间前半个小时比较，取最小时间
        //防止漏掉待处理的订单(系统线上订单半小时后自动置为失败)
        // $endTime = date('Y-m-d H:i:s', min(time()-30*60,strtotime($endTime)));

        $data = DB::table('money_deposit as m')
            ->leftJoin('pay_vendor_scene as pvs', 'pvs.id', '=', 'm.online_pay_id')
            ->leftJoin('pay_vendor as pv', 'pv.id', '=', 'pvs.vendor_id')
            ->select([
                DB::raw("DATE_FORMAT(m.created_at, '%Y-%m-%d') as date"),
                'm.hall_id',
                'm.amount',
                'm.status',
                'm.created_at as last_recharge_time',
                'pvs.scene',
                'pvs.vendor_id',
                'pv.code'
            ])->whereBetween('m.created_at', [$beginTime, $endTime])
            ->where(['m.is_online' => MoneyDepositEnum::IS_ONLINE_TRUE])
            ->whereIn('m.status', [MoneyDepositEnum::STATUS_PAID, MoneyDepositEnum::STATUS_FAILED])
            ->where('m.online_pay_id', '>', 0)
            ->where('pvs.vendor_id', '>', 0)
            ->get()->toArray();
        // $this->error('------'.count($data).'条数据------');
        return $data;
    }

    /**
     * 处理数据
     */
    public function dealData($data)
    {
        $result = [];
        foreach ($data as $key => $value) {
            $value = (array)$value;
            $res = $result[$value['date']][$value['code']][$value['vendor_id']][$value['scene']] ?? [
                    'success_amount' => 0,
                    'failed_amount' => 0,
                    'success_times' => 0,
                    'failed_times' => 0,
                    'first_level_times' => 0,
                    'second_level_times' => 0,
                    'third_level_times' => 0,
                    'fourth_level_times' => 0,
                    'last_recharge_time' => '1970-01-01 00:00:00',
                ];

            $res['hall_id'] = $value['hall_id'];
            $res['date'] = $value['date'];
            $res['code'] = $value['code'];
            $res['vendor_id'] = $value['vendor_id'];
            $res['scene'] = $value['scene'];

            if ($value['status'] == MoneyDepositEnum::STATUS_FAILED) {
                $res['failed_times']++;  //充值失败次数
                $res['failed_amount'] += $value['amount']; //充值失败金额 单位厘
            } else {
                $res['success_times']++;  //充值成功次数
                $res['success_amount'] += $value['amount']; //充值成功金额 单位厘
                //充值成功的最后一笔时间
                $res['last_recharge_time'] = max($res['last_recharge_time'], $value['last_recharge_time']);
                switch (self::getMoneyLevel($value['amount'])) {
                    case ReportOnlineRechargeEnum::FIRST_LEVEL:
                        $res['first_level_times']++; //第一层充值成功次数(1<= money <100)
                        break;
                    case ReportOnlineRechargeEnum::SECOND_LEVEL:
                        $res['deposit_online_times']++; //第二层充值成功次数(100<= money <500)
                        break;
                    case ReportOnlineRechargeEnum::THIRD_LEVEL:
                        $res['deposit_online_times']++; //第三层充值成功次数(500<= money <1000)
                        break;
                    case ReportOnlineRechargeEnum::FOURTH_LEVEL:
                        $res['deposit_online_times']++; //第四层充值成功次数(money >=1000)
                        break;
                    default:
                        break;
                }
            }
            //总的充值金额 = 充值成功金额+充值失败金额
            $res['total_amount'] = $res['success_amount'] + $res['failed_amount'];
            //总充值次数 = 充值成功次数+充值失败次数',
            $res['total_times'] = $res['success_times'] + $res['failed_times'];

            $result[$value['date']][$value['code']][$value['vendor_id']][$value['scene']] = $res;
        }

        foreach ($result as $date => $codeData) {
            foreach ($codeData as $code => $vendorData) {
                foreach ($vendorData as $vendorId => $sceneData) {
                    foreach ($sceneData as $scene => $value) {
                        // $this->error(json_encode($value));
                        // update or insert
                        $model = ReportOnlineRechargeModel::where([
                            'hall_id' => $value['hall_id'],
                            'date' => $value['date'],
                            'code' => $value['code'],
                            'vendor_id' => $value['vendor_id'],
                            'scene' => $value['scene'],
                        ])->first();
                        if (empty($model)) {
                            $model = new ReportOnlineRechargeModel($value);
                        } else {
                            $model->update($value);
                        }
                        if (!$model->save()) {
                            $this->error("{$this->processName} 保存数据失败: " . json_encode($model->getErrors(),
                                    JSON_UNESCAPED_UNICODE));
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    /*
     * 根据充值金额获取金额所属层级
     */
    public static function getMoneyLevel($amount)
    {
        $moneylConfig = ReportOnlineRechargeEnum::MONEY_LEVEL_CONFIG;
        foreach ($moneylConfig as $key => $val) {
            if ($amount >= $val[0] * 1000 AND $amount <= $val[1] * 1000) {
                return $key;
            }
        }
    }
}